<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>[4.2]-开发实战2：模拟优酷开放平台接口项目开发 | PhalApi(π框架) - PHP轻量级开源接口框架 - 助你创造价值！</title>
    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
    <meta content="yes" name="apple-mobile-web-app-capable">
    <meta content="black" name="apple-mobile-web-app-status-bar-style">
    <meta content="telephone=no" name="format-detection">
    <meta content="email=no" name="format-detection">
    <meta name="Author" content="PhalApi,ecitlm,dogstar">
    <meta name="description" content="[4.2]-开发实战2：模拟优酷开放平台接口项目开发，PhalApi是一个PHP轻量级开源接口框架，致力于快速开发接口服务。支持HTTP/SOAP/RPC等协议，可用于搭建接口/微服务/RESTful接口/Web Services。我们不断更新，保持生气；为接口负责，为开源负责！并承诺永久免费！">
    <meta name="keywords" content="PhalApi,phalapi,phalapi接口开发,后台接口开发,后台接口开发框架,接口开发,接口框架,开源接口框架,PHP后台接口开发,PHP接口开发,PHP接口框架,PHP后台接口框架,phalapi官网,PHP接口框架,php接口开发框架,php接口开发,php web框架,π框架,π开发框架,π接口框架,π接口开发框架,api接口,php接口,,PHP接口框架,phalapi文档,phalapi wiki,PhalApi文档,phalapi在线文档,phalapi官方文档">

    <link rel="stylesheet" type="text/css" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" media="screen">
    <link rel="stylesheet" type="text/css" href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.css" media="screen">
    <link rel="stylesheet" href="../css/main.css" />
    <link rel="stylesheet" href="../css/loading_bar.css" />
    <link rel="icon" href="http://webtools.qiniudn.com/dog_catch.png" type="image/x-icon" />
    <script src="../js/pace.min.js"></script>
	
	<!-- 代码高亮 -->
	<link rel="stylesheet" href="../css/highlight.min.css">
	<script src="../js/highlight.min.js"></script>
	<script>hljs.initHighlightingOnLoad();</script>
    
</head>

<body>
    <!-- navbar start -->
    <div class="navbar navbar-default navbar-fixed-top" id="mainnav" role="navigation">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand website_name" href="/"><!-- <span>PhalApi</span> --><strong></strong></a>
            </div>
            <div class="navbar-collapse collapse" aria-expanded="false" style="height: 1px;">
                <ul class="nav navbar-nav navbar-right" id="nav_bar">
                    <li><a href="https://www.phalapi.net/"><span class="glyphicon glyphicon-home"></span></a></li>
                    <li><a href="https://www.phalapi.net/download.html">下载</a></li>
                    <li class="active"><a href="https://www.phalapi.net/wikis/">文档</a></li>
                    <li><a href="https://www.phalapi.net/donate.html">贡献</a></li>
                    <li><a href="#">|</a></li>
                    <li><a href="http://qa.phalapi.net/" target="_blank">社区</a></li>
                    <li><a href="http://www.ituring.com.cn/book/2405" target="_blank">书籍</a></li>
                    <li><a href="http://demo.phalapi.net/listAllApis.php" target="_blank">体验</a></li>
                    <li><a href="https://github.com/phalapi/phalapi-library" target="_blank">扩展</a></li>
                </ul>
            </div>
            <!--/.nav-collapse -->
        </div>
    </div>
    <!-- navbar end -->


    <div id="content">
        <div class="container">
            <div class="row row-md-flex row-md-flex-wrap">
                <h4><a href="#">上一章</a>   <a href="/wikis/">文档首页</a>   <a href="/wikis/%5B4.3%5D-%E5%BC%80%E5%8F%91%E5%AE%9E%E6%88%983%EF%BC%9A%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%E5%B0%8F%E5%9E%8B%E9%A1%B9%E7%9B%AE%E5%BC%80%E5%8F%91%EF%BC%88%E5%A5%94%E8%B7%91%E5%90%A7%E5%85%84%E5%BC%9F%E6%8A%95%E7%A5%A8%E6%B4%BB%E5%8A%A8%EF%BC%89.html">下一章</a></h4>
<hr />
<h2>4.2.1 模拟的业务场景</h2>
<p>在这个开发实战中，我们将模拟实现优酷的开放平台接口，即：<a href="http://open.youku.com/docs"><a href="http://open.youku.com/docs">http://open.youku.com/docs</a></a>  </p>
<p>但这里不涉及具体的内部开发（我们也确实不得而知），而是只从外部的角度，通过PhalApi框架搭建类似的平台接口架构。  </p>
<h2>4.2.2 优酷URL分析与路由Rewrite</h2>
<p>以下是优酷平台的部分接口URL：</p>
<pre><code class="language-php">#单条视频基本信息(videos/show_basic)
https://openapi.youku.com/v2/videos/show_basic.json

#我的详细信息(users/myinfo) 
https://openapi.youku.com/v2/users/myinfo.json

#评论创建(comments/create)
https://openapi.youku.com/v2/comments/create.json

#搜索节目通过关键词(searches/show/by_keyword)
https://openapi.youku.com/v2/searches/show/by_keyword.json
</code></pre>
<p>从上面的接口URL，我们可以明显发现一些规律。即：  </p>
<pre><code>URL =  接口域名 + 版本 + 相对路径.json</code></pre>
<h3>与PhalApi接口规则的冲突</h3>
<p>但在PhalApi框架中，我们是通过&amp;service=XXX参数来指定需要的服务的。为此，我们需要在服务端配置一些Rewrite规则以支持这些URL。
简单地，我们可以这样在nginx配置：</p>
<pre><code class="language-php">    if ( !-f $request_filename )
    {
        rewrite ^/v2/(.*)/(.*).json /v2/?service=$1.$2;
    }
</code></pre>
<p>并为了更兼容PhalApi的风格，我们在入口文件将接收到的service首字母强制为大写，即：  </p>
<pre><code class="language-php">//$ vim ./Public/v2/index.php

if (isset($_REQUEST['service'])) {
    $_REQUEST['service'] = ucwords($_REQUEST['service']);
}</code></pre>
<p>重启一下nginx后，我们可以有浏览器，试着访问：</p>
<pre><code>https://openapi.youku.com/v2/videos/show_basic.json</code></pre>
<p>我们将会看到：  </p>
<pre><code class="language-php">{
    "ret": 400,
    "data": [
    ],
    "msg": "非法请求：接口服务Videos.show_basic不存在"
}</code></pre>
<p>即表明Rewrite规则已生效，并能正常工作了，哈哈！  </p>
<p>以下是更完整的nginx配置：</p>
<pre><code class="language-php">server {
    root /path/to/openapi.youku.com/Public;
    index index.html index.htm index.php;

    error_log /var/log/nginx/.error_log;
    access_log /var/log/nginx/openapi.youku.com.access_log;

    server_name openapi.youku.com;

    location / {
        try_files $uri $uri/ /index.html;
    }

    if ( !-f $request_filename )
    {
        rewrite ^/v2/(.*)/(.*).json /v2/?service=$1.$2;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;

        fastcgi_pass 127.0.0.1:9000;
        include fastcgi_params;
    }

}</code></pre>
<h2>4.2.3 项目的主要目录结构</h2>
<p>首先，我们建立了一个Youku的项目目录，并按不同的版本划分了不同的模块，如：  </p>
<pre><code class="language-php">$ tree ./Youku/
./Youku/
└── V2
    ├── Api
    │   └── Default.php
    ├── Domain
    ├── Model
    └── Tests
        ├── Api
        ├── Domain
        ├── Model
        ├── phpunit_user_getbaseinfo.xml
        ├── phpunit.xml
        └── test_env.php

8 directories, 4 files
</code></pre>
<p>然后，为不同的版本，提供不同的入口，如：  </p>
<pre><code class="language-php">$ tree ./Public/
./Public/
├── checkApiParams.php
├── index.php
├── init.php
└── v2
    ├── checkApiParams.php
    ├── index.php
    └── listAllApis.php

1 directory, 6 files
</code></pre>
<h2>4.2.4 简单的模拟实现</h2>
<p>现在，到了接口具体开发的环节，我们将模拟开发 <a href="http://open.youku.com/docs/docs?id=44">单条视频基本信息(videos/show_basic)</a>  </p>
<p>首先，我们可以定义接口：  </p>
<pre><code class="language-php">//$ vim ./Youku/V2/Api/Videos.php

&lt;?php

class Api_Videos extends PhalApi_Api {

    public function getRules() {
        return array(
            'show_basic' =&gt; array(
                'clientId' =&gt; array('name' =&gt; 'client_id', 'require' =&gt; true, 'desc' =&gt; '应用Key'),
                'videoId' =&gt; array('name' =&gt; 'video_id', 'desc' =&gt; '视频ID'),
                'videoUrl' =&gt; array('name' =&gt; 'video_url', 'desc' =&gt; '视频播放页URL'),
            ),
        );
    }

    /**
     * 单条视频基本信息(videos/show_basic)
     * 
     * @return string id 视频唯一ID 
     * @return string title 视频标题
     * @return string link 视频播放链接
     * @return string thumbnail 视频截图
     * @return int duration 视频时长，单位：秒
     * @return ... ...
     */
    public function show_basic() {

    }
}
</code></pre>
<p>然后，使用浏览器在线访问接口文档，访问：  </p>
<pre><code>http://openapi.youku.com/v2/checkApiParams.php?service=Videos.show_basic</code></pre>
<p>可以看到：<br />
<img src="http://7qnay5.com1.z0.glb.clouddn.com/20150809.png" alt="a pic" /><br />
可以看出，这与优酷平台上的接口文档是非常相近的。  </p>
<p>最后，我们可以简单模拟实现：  </p>
<pre><code class="language-php">    public function show_basic() {
        $rs = '{
            "id" : "XMjg1MTcyNDQ0",
                "title" : "泡芙小姐的灯泡 11",
                "link" : "http://v.youku.com/v_show/id_XMjg1MTcyNDQ0.html",
                "thumbnail" : "http://g4.ykimg.com/0100641F464E1FC...",
                "duration" : "910",
                "category" : "原创",
                "state" : "normal",
                "published" : "2011-07-15 09:00:42",
                "description" : "当一个人在一座城市搬11次家。就意味着准备在这个城市买房了。",
                "player" : "http://player.youku.com/player.php/sid/XMjg1MTcyNDQ0/v.swf",
                "public_type" : "all",
                "copyright_type" : "original",
                "user" :
                {
                    "id" : 58921428,
                    "name" : "泡芙小姐",
                    "link" : "http://u.youku.com/user_show/id_UMjM1Njg1NzEy.html"
                },
                "operation_limit": ["COMMENT_DISABLED"],
                "streamtypes" : ["flv","flvhd","hd"]
        }';

        return json_decode($rs, true);
    }
</code></pre>
<h2>4.2.5 接口调用效果</h2>
<p>虽然是模拟返回（其实是直接强制返回优酷开放平台上的示例数据），但我们还是可以来看下在模拟实现后的接口调用效果。  </p>
<p>首先，是缺少client_id时的非法请求：  </p>
<pre><code class="language-php">#请求
http://openapi.youku.com/v2/videos/show_basic.json

#返回
{
    "ret": 400,
    "data": [
    ],
    "msg": "非法请求：缺少必要参数client_id"
}</code></pre>
<p>然后，尝试一个合法的请求：</p>
<pre><code class="language-php">#请求
http://openapi.youku.com/v2/videos/show_basic.json?client_id=test

#返回
{
    "ret": 200,
    "data": {
        "id": "XMjg1MTcyNDQ0",
        "title": "泡芙小姐的灯泡 11",
        "link": "http://v.youku.com/v_show/id_XMjg1MTcyNDQ0.html",
        "thumbnail": "http://g4.ykimg.com/0100641F464E1FC...",
        "duration": "910",
        "category": "原创",
        "state": "normal",
        "published": "2011-07-15 09:00:42",
        "description": "当一个人在一座城市搬11次家。就意味着准备在这个城市买房了。",
        "player": "http://player.youku.com/player.php/sid/XMjg1MTcyNDQ0/v.swf",
        "public_type": "all",
        "copyright_type": "original",
        "user": {
            "id": 58921428,
            "name": "泡芙小姐",
            "link": "http://u.youku.com/user_show/id_UMjM1Njg1NzEy.html"
        },
        "operation_limit": [
            "COMMENT_DISABLED"
        ],
        "streamtypes": [
            "flv",
            "flvhd",
            "hd"
        ]
    },
    "msg": ""
}</code></pre>
<p>很好，目前运行效果相当流畅。<br />
虽然如此，但我们明显看到了问题所在。  </p>
<h2>4.2.6 返回格式的自行调整</h2>
<p>在上一节中，我们很明显看到了返回格式与优酷现有的不一样，因为PhalApi框架多了一层。<br />
其实，这些调整对于不同的项目来说，都是非常简单。    </p>
<p>当项目需要返回的格式有定制化需求时，可以先自实现response服务，再注册。<br />
在此场景，即：  </p>
<h3>先自定义response服务</h3>
<p>我们先创建一个公共的目录./Youku/Common，再创建项目需要的特定响应类：  </p>
<pre><code class="language-php">//$ vim ./Youku/Common/Response.php

&lt;?php

class Common_Response extends PhalApi_Response_Json {

    public function getResult() {
        return $this-&gt;data;
    }
}
</code></pre>
<h3>注册response服务</h3>
<p>接着，我们对response进行注册：  </p>
<pre><code class="language-php">//$ vim ./Public/v2/index.php

//装载你的接口
DI()-&gt;loader-&gt;addDirs(array('Youku', 'Youku/V2'));

DI()-&gt;response = 'Common_Response';</code></pre>
<p>这里需要稍微注意一下，我们要在装载Youku目录后，才能注册DI()-&gt;response。  </p>
<h3>再次返回</h3>
<p>回到刚才那个请求链接，我们可以发现，当再次调用时，会返回：  </p>
<pre><code class="language-php">{
    "id": "XMjg1MTcyNDQ0",
    "title": "泡芙小姐的灯泡 11",
    "link": "http://v.youku.com/v_show/id_XMjg1MTcyNDQ0.html",
    "thumbnail": "http://g4.ykimg.com/0100641F464E1FC...",
    "duration": "910",
    "category": "原创",
    "state": "normal",
    "published": "2011-07-15 09:00:42",
    "description": "当一个人在一座城市搬11次家。就意味着准备在这个城市买房了。",
    "player": "http://player.youku.com/player.php/sid/XMjg1MTcyNDQ0/v.swf",
    "public_type": "all",
    "copyright_type": "original",
    "user": {
        "id": 58921428,
        "name": "泡芙小姐",
        "link": "http://u.youku.com/user_show/id_UMjM1Njg1NzEy.html"
    },
    "operation_limit": [
        "COMMENT_DISABLED"
    ],
    "streamtypes": [
        "flv",
        "flvhd",
        "hd"
    ]
}</code></pre>
<h2>4.2.7 签名验证</h2>
<p>以上我们调整了返回格式，这使得我们的项目开发，越来越达到优酷开放平台接口的标准了（当然，是假设）。  </p>
<p>但有一点，我们是不能忽视的，在很多项目中同样是不能忽视的。那就是：接口的签名验证。  </p>
<p>我们可以先来看下优酷开放平台是怎么处理接口签名的。  </p>
<p>简单地，优酷会为每一个接入方提供一个client_id，然后在每次接口请求时，通过都需要传递此参数。  </p>
<p>为此，我们针对这个client_id编写一个简单的客户端验证服务。如：  </p>
<pre><code class="language-php">//$ vim ./Youku/Common/ClientCheck.php

&lt;?php

class Common_ClientCheck implements PhalApi_Filter {

    public function check() {
        $clientId = DI()-&gt;request-&gt;get('client_id');

        $allCliendIds = array(
            'phalapi',
            'oschina'
        );

        if (!in_array($clientId, $allCliendIds)) {
            throw new PhalApi_Exception_BadRequest('illegal client id');
        }
    }
}
</code></pre>
<p>然后，在入口处注册一下：</p>
<pre><code class="language-php">//$ vim ./Public/v2/index.php 

DI()-&gt;filter = 'Common_ClientCheck';</code></pre>
<p>当我们，再次打开刚才那个链接：</p>
<pre><code>http://openapi.youku.com/v2/videos/show_basic.json?client_id=test</code></pre>
<p>我们会看到空的返回：</p>
<pre><code class="language-php">[]</code></pre>
<p>这说明，对客户端的非法请求已拦截成功，但这样用户体验明显不好，因为没有任何的错误提示输出。  </p>
<p>为此，我们需要回到刚才自定义的响应类，修改一下：</p>
<pre><code class="language-php">//$ vim ./Youku/Common/Response.php 

&lt;?php

class Common_Response extends PhalApi_Response_Json {

    public function getResult() {
        if ($this-&gt;ret != 200) {
            return array(
                'error' =&gt; array(
                    'code' =&gt; $this-&gt;ret,
                    'type' =&gt; 'SystemException',
                    'description' =&gt; $this-&gt;msg,
                ),
            );
        }

        return $this-&gt;data;
    }
}
</code></pre>
<p>再刷新一下，可以看到和优酷平台接口近似的返回了！  </p>
<pre><code class="language-php">{
    "error": {
        "code": ,
        "type": "SystemException",
        "description": "非法请求：illegal client id"
    }
}</code></pre>
<p>如需要能返回数据，我们只需要传递正确的client_id（目前是固定的两个）即可：</p>
<pre><code>http://openapi.youku.com/v2/videos/show_basic.json?client_id=phalapi</code></pre>
<h2>4.2.8 尾声</h2>
<p>当然，此次的优酷接口模拟开发，我们都只是很简单地表面说明。  </p>
<p>这样的目的，不是为了让大家真的去了解优酷接口的内部实现，而是向大家展示，通过PhalApi框架，我们可以更灵活地实现各种业务需求和非功能性的需求。  </p>
<p>希望对大家有帮助，夜已深，安。  </p>
<h3>源代码请访问：</h3>
<pre><code>https://git.oschina.net/dogstar/PhalApi-Demo-Youku.git</code></pre>
<hr />
<h4><a href="#">上一章</a>   <a href="/wikis/">文档首页</a>   <a href="/wikis/%5B4.3%5D-%E5%BC%80%E5%8F%91%E5%AE%9E%E6%88%983%EF%BC%9A%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%E5%B0%8F%E5%9E%8B%E9%A1%B9%E7%9B%AE%E5%BC%80%E5%8F%91%EF%BC%88%E5%A5%94%E8%B7%91%E5%90%A7%E5%85%84%E5%BC%9F%E6%8A%95%E7%A5%A8%E6%B4%BB%E5%8A%A8%EF%BC%89.html">下一章</a></h4><div style="float: left">
<h4>
<a href="http://qa.phalapi.net/">还有疑问？欢迎到社区提问！</a>
&nbsp;&nbsp;
<a href="http://docs.phalapi.net/#/v2.0/">切换到PhalApi 2.x 开发文档。</a>
</h4>
</div>
            </div>
        </div>
    </div>

 <!-- 广告位 -->
<div class="grid-wrapper desktop-only">
	<p align="center">
		<a href="http://7xiz2f.com1.z0.glb.clouddn.com/%E6%88%91%E7%9A%84%E5%90%8D%E5%AD%97%E5%8F%AB%EF%BC%9A%CF%80%E6%A1%86%E6%9E%B6%20-%20PhalApi%202016%E5%B9%B4%E5%BA%A6%E5%BC%80%E6%BA%90%E6%80%BB%E7%BB%93%20-%20%E5%AE%98%E6%96%B9%E5%87%BA%E5%93%81.pdf" target="blank"><img width="950" height="100" src="http://7xiz2f.com1.z0.glb.clouddn.com/ad_20170104.png"></a>
		<a href="http://www.itran.cc/" target="blank"><img width="950" height="100" src="http://7xslqv.com1.z0.glb.clouddn.com/images/9/69/b88bc92455dc1239f9a5bf8d72929.png"></a>
		<a href="http://web-tools.phalapi.net/" target="blank"><img width="950" height="100" src="http://7xslqv.com1.z0.glb.clouddn.com/images/7/d0/88f523566c482296aecc43d185ca2.png"></a>
	</p>
</div>

        <!-- footer -->
        <div class="footer">
            <div class="link container ">
                <div class=" col-xs-7 col-sm-7 col-md-7 col-lg-7 ">
                    <h3>PhalApi (π框架)</h3>
                    <p>一个轻量级PHP开源接口框架，专注于接口服务开发，支持HTTP/SOAP/RPC协议，拥有自动生成的在线文档、多种开发语言的客户端SDK包以及可重用的扩展类库，可用于快速搭建微服务、RESTful接口或Web
                        Services。</p>
                    <!-- <p>:</p> -->
                    <a href="https://www.phalapi.net/" target="_blank"> PhalApi </a>
                    <span>|</span>
                    <a href="http://qa.phalapi.net/" target="_blank">社区</a>
                    <span>|</span>
                    <a href="download.html" target="_blank">下载</a>
                    <span>|</span>
                    <a href="/wikis/">文档</a>
                    <span>|</span>
                    <a href="http://www.ituring.com.cn/book/2405" target="_blank">书籍</a>
                    <span>|</span>
                    <a href="http://demo.phalapi.net/listAllApis.php" target="_blank">体验</a>
                    <span>|</span>
                    <a href="donate.html" target="_blank">贡献</a>
                    <span>|</span>
                    <a href="https://github.com/phalapi/phalapi-library" target="_blank">扩展</a>
                    <span>|</span>
                    <a href="/license.html" target="_blank">许可</a>
                    <span>|</span>
                    <a href="/about.html" target="_blank">关于</a>
                    <span>|</span>
                    <a href="https://www.phalapi.net/wikis/en/" target="_blank">English</a>

                </div>
                <div class=" col-xs-5 col-sm-5 col-md-5 col-lg-5 contact_us ">
                    <h3>联系我们</h3>
                    <a href="https://github.com/phalapi/phalapi"><img src="../images/github.png" alt="github" /></a>
                    <a href="http://weibo.com/p/100808d236e99beb645bfb56ed1c37dde9b8bd?k=phalapi%E5%BC%80%E6%BA%90%E6%A1%86%E6%9E%B6&from=501&_from_=huati_topic"><img src="../images/weibo.png"  alt="weibo" /></a>
                    <a href="http://7xslqv.com1.z0.glb.clouddn.com/images/1/b0/894fde762850cb11250253f7d5ede.png"><img src="../images/zfb.png"  alt="zfb" /></a>
					<a target="_blank" href="//shang.qq.com/wpa/qunwpa?idkey=f16292029e59975d4ccfccc70ed87aa5c5646df512e83b0e9e1270e8368be461"><img border="0" src="images/qq.png" alt="π框架 - PhalApi交流群②" title="π框架 - PhalApi交流群②"></a>
					<a href="http://git.oschina.net/dogstar/PhalApi"><img src="../images/git-oschina.png"  alt="git-oschina" /></a>
                </div>
                <div class="cls"></div>
                <div class="text-center copy_right"> ©2015-2017 PhalApi All Rights Reserved. <a href="http://www.miitbeian.gov.cn" target="_blank">粤ICP备15028808号</a>

				<script type="text/javascript">var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");document.write(unescape("%3Cspan id='cnzz_stat_icon_1255326144'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "s4.cnzz.com/z_stat.php%3Fid%3D1255326144%26show%3Dpic' type='text/javascript'%3E%3C/script%3E"));</script>
                </div>
            </div>
        </div>
    </div>


    <a href="https://github.com/phalapi"><img id="gitHub_fllow" style="position: fixed; top: 0; right: 0; border: 0;z-index:9999" src="https://camo.githubusercontent.com/652c5b9acfaddf3a9c326fa6bde407b87f7be0f4/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6f72616e67655f6666373630302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png"></a>


    <script src="../js/jquery-1.11.1.min.js"></script>
    <script src="../js/bootstrap.min.js"></script>
</body>

</html>